# coding:utf-8
import logging
from pathlib import Path

import colorlog
from loguru import logger as loguru_logger

from .config import pytest_config, day_time


class PropagateHandler(logging.Handler):
    def emit(self, record):
        logging.getLogger(record.name).handle(record)


class Logger:
    def __init__(self, name=None):
        self.__logger = logging.getLogger(name)
        self.__consoleHandler = logging.StreamHandler()
        pt = Path(pytest_config.report_setting.log_path)
        pt.mkdir(exist_ok=True)
        self.__fileHandler = logging.FileHandler(pt / f'log-{day_time}.log', encoding='utf-8')

        # set log format
        fmt = '%(log_color)s%(asctime)s | %(levelname)-8s | [%(filename)s:%(funcName)s:%(lineno)s] : %(message)s'
        datefmt = '%Y-%m-%d %H:%M:%S'
        consoleFormatter = colorlog.ColoredFormatter(
            fmt, datefmt,
            log_colors={
                'DEBUG': 'cyan',
                'INFO': 'green',
                'WARNING': 'yellow',
                'ERROR': 'red',
                'CRITICAL': 'purple',
            }
        )
        self.setConsoleFormatter(consoleFormatter)
        fileFormatter = logging.Formatter(fmt.replace('%(log_color)s', ''), datefmt)
        self.setFileFormatter(fileFormatter)

        if not self.__logger.hasHandlers():
            self.__logger.addHandler(self.__consoleHandler)
            self.__logger.addHandler(self.__fileHandler)

    def setLevel(self, level: int):
        self.__logger.setLevel(level)
        self.__consoleHandler.setLevel(level)
        self.__fileHandler.setLevel(level)

    def setFormatter(self, fmt: logging.Formatter):
        self.__consoleHandler.setFormatter(fmt)
        self.__fileHandler.setFormatter(fmt)

    def setFileFormatter(self, fmt: logging.Formatter):
        self.__fileHandler.setFormatter(fmt)

    def setConsoleFormatter(self, fmt: logging.Formatter):
        self.__consoleHandler.setFormatter(fmt)

    def debug(self, msg):
        """
        debug level log
        :param msg:
        :return:
        """
        self.__logger.debug(msg, stacklevel=2)

    def info(self, msg):
        """
        info level log
        :param msg:
        :return:
        """
        self.__logger.info(msg, stacklevel=2)

    def error(self, msg, exc_info=False):
        """
        error level log
        :param msg:
        :param exc_info:
        :return:
        """
        self.__logger.error(msg, exc_info=exc_info, stacklevel=2)

    def warning(self, msg):
        """
        warning level log
        :param msg:
        :return:
        """
        self.__logger.warning(msg, stacklevel=2)

    def critical(self, msg):
        """
        critical level log
        :param msg:
        :return:
        """
        self.__logger.critical(msg, stacklevel=2)


def get_logger():
    pt = Path(pytest_config.report_setting.log_path)
    pt.mkdir(exist_ok=True)
    log_path = pt / f'log-{day_time}.log'
    loguru_logger.add(PropagateHandler())
    loguru_logger.add(log_path, encoding='utf-8')

    return loguru_logger


logger = get_logger()
